package me.yangbajing.model

import org.bson.types.ObjectId
import org.squeryl.KeyedEntity
import org.joda.time.DateTime

import net.liftweb.common.{Failure, Box}

import yangbajing.persistence.SquerylEntrypoint._
import yangbajing.util.Pagination
import yangbajing.util.Imports.Y

object MComment {
  def insert(refId: String, creator: String, content: String, email: Option[String] = None, refComment: Option[String] = None): Box[MComment] =
    Y.tryBox {
      require(Y.nonBlank(creator), "用户名不能为空")
      require(Y.nonBlank(content), "评论内容不能为空")
      require(ObjectId.isValid(refId), s"refId: $refId 不是有效的ObjectId")
      email foreach (v => require(Y.emailValidate(v), s"邮箱地址：$v 无效"))
      refComment foreach (id => require(ObjectId.isValid(id), s"引用评论ID: $id 不是有效的ObjectId"))

      val c = new MComment(refId, creator, content, refComment, email = email)
      transaction(Entities.comments insert c)
    }

  def findOne(id: String): Box[MComment] = {
    if (ObjectId.isValid(id))
      transaction(from(Entities.comments)(c => where(c.id === id) select c).singleOption)
    else
      Failure(s"id: $id 不是有效的ObjectId类型")
  }

  def findAll(refId: String, refComment: Option[String]): List[MComment] =
    transaction(from(Entities.comments)(c =>
      where(
        c.ref_id === refId and
          (c.ref_comment === refComment.?)
      ) select c orderBy c.id.desc).toList)

  def size(refId: Option[String] = None, refComment: Option[String] = None): Long =
    transaction(from(Entities.comments)(c =>
      where(
        c.ref_id === refId.? and
          (c.ref_comment === refComment.?)
      ) compute count(c.id)))

  def findAll(offset: Int, limit: Int, refId: Option[String] = None, refComment: Option[String] = None): List[MComment] =
    transaction(from(Entities.comments)(c =>
      where(
        c.ref_id === refId.? and
          (c.ref_comment === refComment.?)
      ) select c orderBy c.id.asc).page(offset, limit).toList)

  def pagination(_curPage: Int, _limit: Int, refId: Option[String] = None, refComment: Option[String] = None) =
    new Pagination[MComment] {
      val curPage = _curPage
      val limit = _limit
      val total = size(refId = refId, refComment = refComment)
      val page = findAll(offset, limit, refId, refComment)
    }
}

case class MComment(
                     ref_id: String,
                     creator: String,
                     content: String,
                     ref_comment: Option[String] = None,
                     created_at: DateTime = DateTime.now(),
                     email: Option[String] = None,
                     score: Int = 0,
                     id: String = ObjectId.get().toString) extends KeyedEntity[String]
